"use client"; import { useQuery } from "@tanstack/react-query"; import { useParams } from "next/navigation"; import { format } from "date-fns"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@nextsparkjs/core/components/ui/card"; import { Button } from "@nextsparkjs/core/components/ui/button"; import { Badge } from "@nextsparkjs/core/components/ui/badge"; import { Avatar, AvatarFallback } from "@nextsparkjs/core/components/ui/avatar"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@nextsparkjs/core/components/ui/table"; import { ArrowLeft, Users2, User, Calendar, Loader2, AlertTriangle, RefreshCw, Crown, Shield, Eye, Mail, CheckCircle2, XCircle, Database, } from "lucide-react"; import Link from "next/link"; import { getTemplateOrDefaultClient } from "@nextsparkjs/registries/template-registry.client"; interface TeamMembership { teamId: string; teamName: string; role: "owner" | "admin" | "member" | "viewer"; joinedAt: string; } interface UserMeta { id: string; metaKey: string; metaValue: unknown; dataType: string | null; isPublic: boolean; isSearchable: boolean; createdAt: string; updatedAt: string; } interface UserDetail { id: string; firstName: string; lastName: string; fullName: string; email: string; role: string; emailVerified: boolean; createdAt: string; updatedAt: string; } interface UserDetailData { user: UserDetail; teams: TeamMembership[]; userMetas: UserMeta[]; stats: { totalTeams: number; workTeams: number; personalTeams: number; ownedTeams: number; }; metadata: { requestedBy: string; requestedAt: string; source: string; }; } const roleIcons = { owner: Crown, admin: Shield, member: User, viewer: Eye, }; const roleColors = { owner: "destructive", admin: "default", member: "secondary", viewer: "outline", } as const; /** * User Detail Page * * Displays detailed information about a specific user for superadmins. */ function UserDetailPage() { const params = useParams()!; const userId = params.userId as string; // Fetch user data from API const { data: userData, isLoading, error, refetch } = useQuery({ queryKey: ["superadmin-user", userId], queryFn: async () => { const response = await fetch(`/api/superadmin/users/${userId}`); if (!response.ok) { if (response.status === 404) { throw new Error("User not found"); } throw new Error("Failed to fetch user data"); } return response.json(); }, retry: 2, staleTime: 30000, }); // Get user initials for avatar const getUserInitials = (firstName: string, lastName: string, email: string) => { if (firstName && lastName) { return `${firstName[0]}${lastName[0]}`.toUpperCase(); } if (firstName) { return firstName.slice(0, 2).toUpperCase(); } return email.slice(0, 2).toUpperCase(); }; // Loading state if (isLoading) { return (

User Details

Loading user data...

); } // Error state if (error) { return (

User Details

Error loading data

Error Loading User {error instanceof Error ? error.message : "Failed to load user data"}
); } const user = userData?.user; const teams = userData?.teams || []; const userMetas = userData?.userMetas || []; const stats = userData?.stats; return (
{/* Header */}

User Details

View user information and team memberships

{/* User Info Card */}
{user ? getUserInitials(user.firstName, user.lastName, user.email) : "??"}
{user?.fullName} {user?.role === "superadmin" ? ( <> Superadmin ) : ( <> {user?.role || "User"} )} {user?.emailVerified ? ( <> Verified ) : ( <> Unverified )}
ID: {user?.id}
{/* Email */}

Email

{user?.email}
{/* Registered */}

Registered

{user?.createdAt ? format(new Date(user.createdAt), "MMMM dd, yyyy") : "Unknown"}
{/* Last Updated */}

Last Updated

{user?.updatedAt ? format(new Date(user.updatedAt), "MMMM dd, yyyy") : "Unknown"}
{/* Stats Cards */}
Total Teams
{stats?.totalTeams || 0}

All team memberships

Owned Teams
{stats?.ownedTeams || 0}

As team owner

{/* Team Memberships Table */} Team Memberships ({teams.length}) All teams this user belongs to and their roles. {teams.length === 0 ? (

No team memberships

This user is not a member of any teams yet.

) : (
Team Role Joined Actions {teams.map((team) => { const RoleIcon = roleIcons[team.role] || User; return (
{team.teamName}
{team.role.charAt(0).toUpperCase() + team.role.slice(1)}
{team.joinedAt ? format(new Date(team.joinedAt), "MMM dd, yyyy") : "Unknown"}
); })}
)}
{/* User Metadata Card */} User Metadata ({userMetas.length}) All metadata records stored for this user. {userMetas.length === 0 ? (

No metadata

This user has no metadata records yet.

) : (
Key Value Type Public Searchable Updated {userMetas.map((meta) => ( {meta.metaKey}
                          {typeof meta.metaValue === "object"
                            ? JSON.stringify(meta.metaValue, null, 2)
                            : String(meta.metaValue)}
                        
{meta.dataType || "json"} {meta.isPublic ? ( Yes ) : ( No )} {meta.isSearchable ? ( Yes ) : ( No )}
{meta.updatedAt ? format(new Date(meta.updatedAt), "MMM dd, yyyy") : "Unknown"}
))}
)}
{/* Metadata Footer */} {userData?.metadata && (

Last updated:{" "} {new Date(userData.metadata.requestedAt).toLocaleString()}

Requested by: {userData.metadata.requestedBy}

Source: {userData.metadata.source}

)}
); } export default getTemplateOrDefaultClient( "app/superadmin/users/[userId]/page.tsx", UserDetailPage );